﻿using Microsoft.Extensions.DependencyInjection;
using System.Threading;
using VIA.Integration;
using VIA.Integration.Alarms;
using VIA.Integration.Domain;
using VIA.Integration.LeadShine;
using VIA.Project.Domain.Services;
using VIA.SiMoJi.Domain.Electronics;
using VIA.SiMoJi.Domain.Option;
using VMathNet.Numerics;
using static OpenCvSharp.Stitcher;

namespace VIA.SiMoJi.Domain.Inspection
{
    public class Feeder : Automatic, IHasOption<FeiDaStationOption>, IRefreshing, ISuportInitialization, ISuportClearAlarm
    {
        public volatile SiMoStation SiMoStation;

        public const string A供料速度 = "A供料速度";

        private double _emptyLength = 300;
        private double _moWidth = 15;
        private int _distCount = 2;
        private double _jawDist = 200;
        public FeiDaRunningStatus Status;
        private bool readyError;
        private bool fullError;
        private bool emptyError;
        private bool vacuoError;
        private InspectorOption _inspectorOption;

        public Electronic Electronic => Electronic.Default;
        public event EventHandler<int> StepCountChanged;
        /// <summary>
        /// 标识飞达1和2
        /// </summary>
        public int Flag { get; private set; }
        [MotionPath(A供料速度)]
        public DmcAxis Axis { get; private set; }
        public CylinderEx YaLiao_Cylinder { get; private set; }
        public CylinderEx DingWei_Cylinder { get; private set; }
        public IoPoint DO_飞达抽屉按钮灯 { get; private set; }
        public EventButton DI_飞达抽屉按钮 { get; private set; }
        public EventButton DI_飞达抽屉闭合光电按钮 { get; private set; }
        public IoPoint DI_飞达料带有无检测 { get; private set; }
        public IoPoint DI_飞达放置到位 { get; private set; }
        public IoPoint DI_飞达收料触发 { get; private set; }
        public IoPoint DI_飞达满料检测 { get; private set; }
        public bool IsReverse { get; }
        public int Count { get; set; } = 1;

        #region Alarm

        [Alarm(true, AlarmLevel.Warning, "飞达未就绪", Logical.Equal)]
        public bool ReadyError { get => readyError; set => NotifyAlarm(ref readyError, value); }
        [Alarm(true, AlarmLevel.Warning, "飞达满料报警", Logical.Equal)]
        public bool FullError { get => fullError; set => NotifyAlarm(ref fullError, value); }
        [Alarm(true, AlarmLevel.Warning, "飞达缺料报警", Logical.Equal)]
        public bool EmptyError { get => emptyError; set => NotifyAlarm(ref emptyError, value); }
        [Alarm(true, AlarmLevel.Warning, "飞达真空异常", Logical.Equal)]
        public bool VacuoError { get => vacuoError; set => NotifyAlarm(ref vacuoError, value); }
        public FeiDaStationOption Option { get; set; }
        #endregion

        public Feeder(DmcAxis axis, CylinderEx yamoCylinder, CylinderEx dingweiCylinder, IoPoint 飞达抽屉按钮灯, EventButton 飞达抽屉按钮, EventButton 飞达抽屉闭合光电IO, IoPoint 飞达有无检测IO, IoPoint 飞达放置到位IO, IoPoint 飞达收料触发IO, IoPoint 飞达满料检测IO, bool isReverse)
        {
            this.InitalizeAlarms();
            Axis = axis;
            YaLiao_Cylinder = yamoCylinder;
            DingWei_Cylinder = dingweiCylinder;
            DO_飞达抽屉按钮灯 = 飞达抽屉按钮灯;
            DI_飞达抽屉按钮 = 飞达抽屉按钮;
            DI_飞达抽屉按钮.Pressed += DI_飞达抽屉按钮_Pressed;
            DI_飞达抽屉按钮.Released += DI_飞达抽屉按钮_Released;
            DI_飞达抽屉闭合光电按钮 = 飞达抽屉闭合光电IO;
            DI_飞达抽屉闭合光电按钮.Pressed += DI_飞达抽屉闭合光电按钮_Pressed;
            DI_飞达抽屉闭合光电按钮.Released += DI_飞达抽屉闭合光电按钮_Released;
            DI_飞达料带有无检测 = 飞达有无检测IO;
            DI_飞达放置到位 = 飞达放置到位IO;
            DI_飞达收料触发 = 飞达收料触发IO;
            DI_飞达满料检测 = 飞达满料检测IO;
            IsReverse = isReverse;
        }

        /// <summary>
        /// 检测飞达是否就绪
        /// </summary>
        /// <returns></returns>
        public bool CheckIsReady()
        {
            bool b = true;
            if (!DI_飞达料带有无检测.Value)
            {
                EmptyError = true;
                b = false;
            }
            if (DI_飞达满料检测.Value)
            {
                FullError = true;
                b = false;
            }
            else if (DI_飞达抽屉闭合光电按钮.PressedIo.Value == false)
            {
                ReadyError = true;
                b = false;
            }
            if (DI_飞达放置到位.Value)
            {
                VacuoError = true;
            }
            b &= b && !DI_飞达抽屉按钮.IsPressed && DI_飞达抽屉闭合光电按钮.PressedIo.Value /*&& DI_飞达放置到位.Value*/;
            return b;
        }

        private async void DI_飞达抽屉按钮_Pressed(object? sender, EventArgs e)
        {
            DO_飞达抽屉按钮灯.Value = true;
            await DingWei_Cylinder.TakeBackAsync();
        }

        private async void DI_飞达抽屉按钮_Released(object? sender, EventArgs e)
        {
            await Task.Delay(100);
            DO_飞达抽屉按钮灯.Value = false;
        }

        private async void DI_飞达抽屉闭合光电按钮_Pressed(object? sender, EventArgs e)
        {
            await Task.Delay(500);
            await DingWei_Cylinder.PushOutAsync();
        }

        private async void DI_飞达抽屉闭合光电按钮_Released(object? sender, EventArgs e)
        {
        }

        public void ClearAlarm()
        {
            ReadyError = false;
            FullError = false;
            EmptyError = false;
            VacuoError = false;
            Axis.ClearAlarm();
            YaLiao_Cylinder.ClearAlarm();
            DingWei_Cylinder.ClearAlarm();
        }

        public async Task<int> NianMo(double stepDistance, double longDistance, int steps, CancellationToken cancellationToken)
        {
            if (IsReverse)
            {
                stepDistance = -stepDistance;
                longDistance = -longDistance;
            }
            YaLiao_Cylinder.TakeBack();//张开
            Count++;
            if (Count >= steps)
            {
                await Axis.MoveDeltaAsync(longDistance, null, cancellationToken);
                Count = 0;
            }
            else
            {
                await Axis.MoveDeltaAsync(stepDistance, null, cancellationToken);
            }
            StepCountChanged?.Invoke(this, Count);
            return Count;
        }

        double needPos = 0;
        public bool IsMoveNianMoDone { get; private set; }//步进距离飞达移动完成
        public async Task<int> NianMo2(double stepDistance, double longDistance, int steps, CancellationToken cancellationToken, bool isFirst)
        {
            if (IsReverse)
            {
                stepDistance = -stepDistance;
                longDistance = -longDistance;
            }
            if (isFirst && IsMoveNianMoDone == false)
            {
                return Count;
            }
            YaLiao_Cylinder.TakeBack();//张开
            double distance = 0;
            if (IsMoveNianMoDone)
            {
                distance = needPos - Axis.Current;
            }
            else
            {
                Count++;
                if (Count >= steps)
                {
                    distance = longDistance;
                    Count = 1;
                }
                else
                {
                    distance = stepDistance;
                }
            }
            var velocityCurve = Axis.GetVelocityCurve("运行高速");
            needPos = Axis.Current + distance;
            IsMoveNianMoDone = true;
            await Axis.MoveDeltaAsync(distance, velocityCurve, cancellationToken);
            IsMoveNianMoDone = false;
            StepCountChanged?.Invoke(this, Count);
            return Count;
        }
        public async Task AxisMoveAsync(double distance)
        {
            if (IsReverse)
            {
                distance = -distance;
            }
            YaLiao_Cylinder.TakeBack();//张开
            await Axis.MoveDeltaAsync(distance);
        }

        public async Task InitializeAsync()
        {
            //Status = RunningStatus.GetRecord<FeiDaRunningStatus>($"FeiDa{Name}.json");
            var repository = Service.GetRequiredService<IOptionRepository>();
            _inspectorOption = repository.Get<InspectorOption>();
        }

        public void Refresh()
        {
            DI_飞达抽屉按钮.Check();
            DI_飞达抽屉闭合光电按钮.Check();
        }

        public void Refreshing()
        {
        }
    }
}
